
#include <string.h>
#include <stdio.h>
#include <stdarg.h>


#define tc_log(_fmt_, ...) \
		printf("[TC][%s:%d][%s] "_fmt_"\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)
#define tc_log_err(_fmt_, ...) \
		printf("[TC][ERR][%s:%d][%s] "_fmt_"\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__)


static void hexdump(const void *data, size_t size, const char *str, ...)
{
    char t_str[128];
    char hexByte[4];
    char hexLine[50];
    char charByte[2];
    char charLine[18];
    unsigned int i;

    va_list args;
    va_start(args, str);
    int len = vsnprintf(t_str, sizeof(t_str), str, args);
    va_end(args);
    printf("%.*s\r\n", len, t_str);

    for (i = 0; i < size; i++) {
        if (i % 16 == 0) {
            hexLine[0] = 0;
            charLine[0] = 0;
        }
        if (i % 16 == 8) {
            strcat(hexLine, " ");
            strcat(charLine, " ");
        }
        dna_snprintf(hexByte, sizeof(hexByte), " %02x", ((unsigned char *) data)[i]);
        strcat(hexLine, hexByte);
        if (((unsigned char *) data)[i] < 32 || ((unsigned char *) data)[i] > 126) {
            strcat(charLine, ".");
        } else {
            dna_snprintf(charByte, sizeof(charByte), "%c", ((unsigned char *) data)[i]);
            strcat(charLine, charByte);
        }
        if (i % 16 == 15 || i == size - 1) {
            printf("%04x:%-49s  %s\r\n", i & ~15, hexLine, charLine);
        }
    }
}

/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** transpose(int** A, int ASize, int* AColSize, int* returnSize, int** returnColumnSizes){
	int i, j;
	int BSize = AColSize[0];
	int *BColSize = (int *)malloc(sizeof(int) * BSize);
	for (i = 0; i < BSize; ++i) {
		BColSize[i] = ASize;
	}

	int **B = (int **)malloc(sizeof(int *) * BSize);
	for (i = 0; i < BSize; ++i) {
		B[i] = (int *)malloc(sizeof(int) * BColSize[i]);
		for (j = 0; j < BColSize[i]; ++j) {
			*(B[i] + j) = *(A[j] + i);
		}
	}

	*returnSize = BSize;
	*returnColumnSizes = BColSize;
	return B;
}

int main(int argc, char const *argv[])
{
	tc_log("********************");
	tc_log("new start @ %s %s", __DATE__, __TIME__);
	tc_log("********************");

	int arr[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
	int i, j;

	/* A是行数组首地址的连续指针，分别指向各行数组的地址，所以是指针的指针 */
	int **A = (int **)malloc(sizeof(int *) * 3);
	for (i = 0; i < 3; ++i) {
		A[i] = (int *)malloc(sizeof(int) * 3);
	}
	printf("origin:\n");
	for (i = 0; i < 3; ++i) {
		for (j = 0; j < 3; ++j) {
			*(A[i] + j) = arr[i][j];
			printf("%8d", *(A[i] + j));
		}
		printf("\n");
	}

	int ASize = 3;
	int *AColSize = (int *)malloc(sizeof(int) * 3);
	AColSize[0] = 3;
	AColSize[1] = 3;
	AColSize[2] = 3;

	int returnSize;
	int *returnColumnSizes;
	int **B;

	B = transpose(A, ASize, AColSize, &returnSize, &returnColumnSizes);

	printf("after:\n");
	for (i = 0; i < returnSize; ++i) {
		for (j = 0; j < returnColumnSizes[i]; ++j) {
			printf("%8d", *(B[i] + j));
		}
		printf("\n");
	}

	tc_log("exit");
	return 0;
}

